#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "setupdialog.h"
#include "addfilmdialog.h"
#include "aboutdialog.h"
#include "printscpthread.h"
#include "dicomprintthread.h"
#include "systrayicon.h"

#include <QDateTime>
#include <QNetworkInterface>
#include <QSettings>
#include <QCloseEvent>

MainWindow::MainWindow(QWidget *parent) :
    trayIcon(new SysTrayIcon(this)),
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    connect(ui->setupButton, SIGNAL(clicked()), this, SLOT(onSetup()));
    connect(ui->addFilmButton, SIGNAL(clicked()), this, SLOT(onAddFilm()));
    connect(ui->aboutButton, SIGNAL(clicked()), this, SLOT(onAbout()));
    connect(ui->quitButton, SIGNAL(clicked()), this, SLOT(close()));

    connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
            this, SLOT(show()));
    connect(trayIcon, SIGNAL(quitApp()), this, SLOT(close()));
    connect(trayIcon, SIGNAL(restoreWindow()), this, SLOT(show()));
    connect(trayIcon, SIGNAL(restoreWindow()), trayIcon, SLOT(hide()));

    init();
}

MainWindow::~MainWindow()
{
    printscp->terminate();
    printscp->wait(6000);
    delete ui;
}

void MainWindow::init()
{
    SetupDialog::getConfigDataFromFile(ruleList, general, format, paperMap);
    printscp = new PrintScpThread(general.port, this);
    connect(printscp, SIGNAL(threadStatus(int,QString)),
            this, SLOT(sys_log(int,QString)));
    connect(printscp, SIGNAL(printJob(QString)), this, SLOT(onPrintJob(QString)));
    printscp->start();

    QList<QHostAddress> ads = QNetworkInterface::allAddresses();
    QStringList ips;
    foreach (QHostAddress ad, ads) {
        if (!(ad.isNull() || ad.isLoopback() || ad.protocol()==QAbstractSocket::IPv6Protocol))
            ips << ad.toString();
    }
    ui->ipLabel->setText(tr("Local IP: %1").arg(ips.join(' ')));

    updateFilmCounter();
}

void MainWindow::sys_log(int level, const QString &msg)
{
    switch (level) {
    case LL_Info:
        if (general.log <= LL_Info)
            ui->infoTextBrowser->append(tr("%1  %2: \n    %3")
                                        .arg(tr("Info"),
                                             QDateTime::currentDateTime().toString("yyyy/MM/dd hh:mm:ss"),
                                             msg));
        break;
    case LL_Warn:
        if (general.log <= LL_Warn)
            ui->infoTextBrowser->append(tr("%1  %2: \n    %3")
                                        .arg(tr("Warn"),
                                             QDateTime::currentDateTime().toString("yyyy/MM/dd hh:mm:ss"),
                                             msg));
        break;
    case LL_Error:
        ui->infoTextBrowser->append(tr("%1  %2: \n    %3")
                                    .arg(tr("Error"),
                                         QDateTime::currentDateTime().toString("yyyy/MM/dd hh:mm:ss"),
                                         msg));
        break;
    }
}

void MainWindow::updateFilmCounter()
{
    QSettings settings;
    ui->usedFilmLabel->setText(tr("Film Used: %1").arg(settings.value(FILM_USED).toULongLong()));
    ui->availFilmLabel->setText(tr("Film Avail: %1").arg(getFilmCount()));
}

void MainWindow::onPrintJob(const QString &printerAE)
{
    DicomPrintThread *thread = new DicomPrintThread(printerAE, &mutex);
    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    connect(thread, SIGNAL(finished()), this, SLOT(updateFilmCounter()));
    connect(thread, SIGNAL(threadMsg(int,QString)), this, SLOT(sys_log(int,QString)));
    thread->setPrintRules(ruleList, format, paperMap);
    thread->start();
}

void MainWindow::onSetup()
{
    SetupDialog dialog(this);
    if (QDialog::Accepted == dialog.exec()) {
        ruleList.clear();
        dialog.getConfigData(ruleList, general, format, paperMap);
    }
}

void MainWindow::onAddFilm()
{
    AddFilmDialog dialog(this);
    if (QDialog::Accepted == dialog.exec()) {
        sys_log(LL_Info, tr("%1 films added.").arg(dialog.getAddedFilmCount()));
        updateFilmCounter();
    }
}

void MainWindow::onAbout()
{
    AboutDialog dialog(this);
    dialog.exec();
}

void MainWindow::changeEvent(QEvent *e)
{
    if ((e->type() == QEvent::WindowStateChange) &&
            (windowState() & Qt::WindowMinimized) &&
            general.miniToTray) {
        hide();
        trayIcon->show();
    }

    QMainWindow::changeEvent(e);
}

void MainWindow::closeEvent(QCloseEvent *e)
{
    if (general.saveLog) {
        QString logName = QString("%1/%2.log").arg(general.logDir,
                                                   QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz"));
        QFile logFile(logName);
        if (logFile.open(QIODevice::WriteOnly)) {
            QTextStream out(&logFile);
            out << ui->infoTextBrowser->toPlainText();
            logFile.close();
        }
    }

    QMainWindow::closeEvent(e);
}
